using System;
using System.Collections.Generic;
using BruteForce.Characters;
using BruteForce.Screens.CreateNewCharacterScreen;
using BruteForce.Screens.CreditsScreen;
using BruteForce.Screens.Instructions;
using BruteForce.Screens.MenuScreen;
using BruteForce.Screens.PlayingScreen;
using BruteForce.Screens.PlayingScreen.Panels;
using BruteForce.UserInterface.Abstracts;
using BruteForce.UserInterface.Interfaces;
using BruteForce.Utilities;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;

namespace BruteForce.NewManagers
{
    /// <summary>
    /// This is a game component that implements IUpdateable.
    /// </summary>
    public class ScreenManager : Manager
    {
        public static ScreenManager Instance = new ScreenManager();

        public MonitoredProperty<IScreen> CurrentScreen = new MonitoredProperty<IScreen>(null);
        public Stack<IScreen> Screens = new Stack<IScreen>();
        private bool _initialized;


        public override void Draw(GameTime gameTime, BFGame game)
        {
            if (Screens.Count > 0)
            {
                Screens.Peek().Draw(gameTime);
            }
        }

        protected override void _Update(GameTime gameTime, BFGame game)
        {
            if (Screens.Count > 0)
            {
                Screens.Peek().Update(gameTime);
            }
        }

        public override void LoadContent(ContentManager content)
        {
            GamePanel.LoadContent(content);
        }

        public override void Initialize()
        {
            _initialized = true;
            var firstScreen = new StartingMenuScreen();
            //            firstScreen.AfterLayout();
            PushScreen(firstScreen);
        }


        /// <summary>
        /// Allows the game component to update itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public void Update(GameTime gameTime)
        {
            //todo check _lastKnowedLoopIndex
            Peek().Update(gameTime);
        }


        public void Draw(GameTime gameTime)
        {
            Peek().Draw(gameTime);
        }


        public void PushScreen(AbstractScreen newScreen)
        {
            newScreen.AfterLayout();
            if (!_initialized) throw new Exception("not initialized yet");
            Screens.Push(newScreen);
            CurrentScreen.Property = newScreen;
        }

        public void OpenNewCharacterScreen()
        {
            GamePanel.Current.StopGeneration();
            InputManager.Instance.Generated();
            AbstractScreen createNewCharacterScreen = new CreateNewCharacterScreen();
            PushScreen(createNewCharacterScreen);
            createNewCharacterScreen.AfterLayout();
        }

        public void CloseNewCharacterScreen(CreateNewCharacterPanel createNewCharacterPanel)
        {
            if (createNewCharacterPanel.ChosenCharacter != CharacterType.None)
            {
                if (createNewCharacterPanel.IsEnoughResources(createNewCharacterPanel.GetPlayerRecourcesMinusSliders()))
                {
                    InputManager.Instance.Generate(createNewCharacterPanel.ChosenCharacter);
                    GamePanel.Current.Generate(createNewCharacterPanel.ChosenCharacter, createNewCharacterPanel.GetSliderRecources());
                }
            }

            if (Peek() is CreateNewCharacterScreen)
            {
                PopScreen();
            }
        }

        public void CancelScreenCreatNewCharacter()
        {
            if (Peek() is CreateNewCharacterScreen)
            {
                PopScreen();
            }
        }

        public IScreen PopScreen()
        {
            IScreen screen = Screens.Pop();
            CurrentScreen.Property = Peek();

            return screen;
        }

        public IScreen Peek()
        {
            return Screens.Peek();
        }

        public void StartNewGame()
        {
            PlayerManager.Instance.Reset();
            var mapFile = "../../../../map.xml";
            PushScreen(new PlayingScreen(100, 50, mapFile, false));
        }

        public Boolean CheckIfCanResume()
        {
            return Screens.Peek() is PlayingScreen;
        }

        public void StartNewTutorial()
        {
            PlayerManager.Instance.Reset();
            var mapFile = "../../../../tut.xml";
            PushScreen(new PlayingScreen(39, 20, mapFile, true));
        }

        public void ShowCredits()
        {
            PushScreen(new CreditsScreen());
        }

        public void showTotorial()
        {
            //todo
        }



        public void StartInstructions()
        {
            PushScreen(new InstructionsScreen());
        }
    }
}